<template>
  <div v-if="showCurrentConversation">
    <p id="app1">{{ friend.name }}</p>
    <!--      显示会话内容 , 聊天记录 -->
    <div class="chat" ref="message-list" @scroll="onScroll">
      <!--        显示是否展示了 所有的聊天消息-->
      <div v-if="!isCompleted" class="more">
        <el-button
          type="text"
          @click="getMoreMessageList"
        >查看更多
        </el-button>
      </div>
      <div v-else class="no-more">没有更多了</div>
      <!--      循环聊天记录 , 打印每一条消息-->
      <!--        判断 消息 , 是否是自定义的消息 , 如果不是自定义的消息 , 则不展示 , 给每一个消息 , 指定一个右键点击事件-->
      <div
        class="chat-message"
        v-for="message in currentMessageList"
        :key=message.ID
        v-if="message.type != 'TIMCustomElem'"
      >
        <!--        消息时间-->
        <div
          class="message-date"
          :class="isMine(message)?
              'message-date-right' :
              'message-date-left'">
          {{ formatTime(message.time) }}
        </div>
        <!--        创建一个容器 , 来存放 , 用户的头像 , 以及 , 发送的消息(消息包含 , 消息内容 , 消息的箭头)-->
        <div class="message-info"
             :class="[isMine(message) ?'message-info-right':'message-left']">
          <!-- 聊天记录头像 -->
          <div class="message-avatar"
               :class="[isMine(message) ?
                'el-avatar-right' :
                'el-avatar-left']">
            <el-avatar :size="50"
                       class="avatar"
                       :src="isMine(message) ? avatar : friend.url"/>
          </div>
          <!--          消息 内容(文本 , 箭头) , 给消息 ,指定一个淡出框 , 来进行撤回消息-->
          <div class="chat-text"
               :class="[isMine(message) ?
               'chat-text-right':'chat-text-left']">

            <!--            判断 消息的类型 , 是什么样的消息 -->
            <div v-if="message.type === 'TIMTextElem'">
              <!--              判断,  消息是否是空的消息 , 如果是空的消息-->
              <template v-for="(item,index) in contentList(message)">
                <!--            显示文字-->
                <span v-if="item.name === 'text'" :key="index">{{ item.text }}</span>
                <!--            显示表情-->
                <img
                  v-else-if="item.name === 'img'"
                  :key="index"
                  :src="item.src"
                  width="20px"
                  height="20px"
                >
              </template>
            </div>
            <!--            显示 图片消息  TIMImageElem -->
            <div v-else-if="message.type === 'TIMImageElem'">
              <span>
              <img
                style="height: 150px;width:200px"
                :src="message.payload.imageInfoArray[0].imageUrl">
                </span>
            </div>
            <!--            展示视频消息-->
            <div v-else-if="message.type === 'TIMVideoFileElem'">
                       <span>
                          <video width="350px" height="200px" controls>
                            <source :src="message._elements[0].content.videoUrl">
                          </video>
                        </span>
              <!--      显示上传图片,  上传视频的进度条-->
              <el-progress
                v-if="message.status === 'unSend'"
                :percentage="percentage(message)"
                :color="customColorMethod(percentage(message))"
              />
            </div>
            <!--            展示文件消息-->
            <div v-else-if="message.type === 'TIMFileElem'">
              <message-bubble :message="message">
                <div class="file-element-wrapper" title="单击下载" @click="downloadFile(message)">
                  <!--                 展示文件-->
                  <div class="file-element">
                    <!--                    文件的名字-->
                    <span class="file-name">{{ message.payload.fileName }}</span>
                    <!--                    文件的大小-->
                    <span class="file-size">{{ filesize(message) }}</span>
                  </div>
                  <el-progress
                    v-if="message.status === 'unSend'"
                    :percentage="percentage(message)"
                    :color="customColorMethod(percentage(message))"
                  />
                </div>
              </message-bubble>
            </div>
          </div>
          <!--            展示消息 , 是否已读-->
          <div class="isRead" v-if="isMine(message)">
            <span>{{ messageReadByPeer(message) }}</span>
          </div>
        </div>
      </div>
    </div>
    <div
      v-show="isShowScrollButtomTips"
      class="newMessageTips"
      @click="scrollMessageListToButtom"
    >
      回到底部
    </div>
    <!--    发送消息的输入框-->
    <div id="app2">
      <MessageBox/>
    </div>
  </div>
</template>

<script>
// 引入发送消息的输入框的子组件
import MessageBox from "./MessageSendBox"
import {mapGetters, mapState} from "vuex";
import {decodeText} from "./decodeText";

export default {
  name: "currentConversation2",
  components: {MessageBox},
  data() {
    return {
      //是否显示回到底部
      isShowScrollButtomTips: false,
      //指定是否回到最新的位置
      preScrollHeight: 0,
      textarea: null,
      timeout: '',
    }
  },
  //  计算属性
  computed: {
    //引入当前用户的个人信息
    ...mapGetters(['id', 'name', 'friends', 'avatar']),
    //引入 当前操作的会话对象
    //引入用户的会话列表 ///用户当前操作的会话
    ...mapState({
      currentConversation: (state) => state.timMessage.currentConversation,
      //当前会话的聊天记录
      currentMessageList: (state) => state.timMessage.currentMessageList,
      //当前会话是否已经拉完了所有的消息
      isCompleted: (state) => state.timMessage.isCompleted,
    }),
    //是否显示当前会话的组件
    showCurrentConversation() {
      return !!this.currentConversation.conversationID
    },
    //获取当前操作的用户朋友的信息
    friend() {
      //获取当前操作的会话的id
      var currentconverid = this.conversationId();
      //  通过id , 到朋友列表中 , 查询到用户的信息 , 进行展示
      for (let i = 0; i < this.friends.length; i++) {
        //  判断 , 用户 , 是否相同 , 如果相同 , 则把用户的信息 , 返回出去
        if (this.friends[i].id == currentconverid) {
          return this.friends[i];
        }
        console.log("没有找到该用户");
      }
    },
  },
  mounted() {
    //  添加监听
    this.$bus.$on('image-loaded', this.onImagesLoaded)
    this.$bus.$on('scroll-bottom', this.scrollMessageListToButtom)
  },
  beforeDestroy() {
    // 移除监听
    this.$bus.$off('image-loaded')
    this.$bus.$off('scroll-bottom')
  },
  //函数
  methods: {
    //计算文件的大小
    filesize(message) {
      const size = message.payload.fileSize
      if (size > 1024) {
        if (size / 1024 > 1024) {
          return `${this.toFixed(size / 1024 / 1024)} Mb`
        }
        return `${this.toFixed(size / 1024)} Kb`
      }
      return `${this.toFixed(size)}B`
    },
    toFixed(number, precision = 2) {
      // 保留2位小数
      return number.toFixed(precision)
    },
    //下载文件 ,
    downloadFile(message) {
      // 文件地址
      const fileUrl = message.payload.fileUrl
      // 浏览器支持fetch则用blob下载，避免浏览器点击a标签，跳转到新页面预览的行为
      if (window.fetch) {
        fetch(fileUrl)
          .then((res) => res.blob())
          .then((blob) => {
            const a = document.createElement('a')
            const url = window.URL.createObjectURL(blob)
            a.href = url
            a.download = message.payload.fileName
            a.click()
          })
      } else {
        const a = document.createElement('a')
        a.href = fileUrl
        a.target = '_blank'
        a.download = message.payload.fileName
        a.click()
      }
    },
    //图片加载事件回调
    onImagesLoaded() {
      this.KeepMessageListOnButtom();
    },
    //如果滚动到底部 , 则保存到底部 , 赋值提示滚动到底部
    KeepMessageListOnButtom() {
      const messageListNode = this.$refs['message-list']
      if (!messageListNode) {
        return;
      }
      // 距离底部20px内强制滚到底部,否则提示有新消息
      if (this.preScrollHeight - messageListNode.clientHeight - messageListNode.scrollTop < 20) {
        console.log('强制滚到到底部查看最新消息')
        this.scrollMessageListToButtom()
      } else {
        console.log('显示回到最新位置提示')
        this.isShowScrollButtomTips = true;
      }
      this.preScrollHeight = messageListNode.scrollHeight
    },
    //指定滚动条的颜色
    customColorMethod(percentage) {
      if (percentage < 30) {
        return '#909399';
      } else if (percentage < 70) {
        return '#e6a23c';
      } else {
        return '#67c23a';
      }
    },
    //判断 , 消息 , 地方是否已读
    messageReadByPeer(message) {
      //  判断消息的状态
      if (message.status !== 'success') {
        return '正在发送'
      }
      //判斷已读
      if (message.conversationType === 'C2C' && message.isPeerRead) {
        return "已读"
      }
      //判断 , 未读
      if (message.conversationType === 'C2C' && !message.isPeerRead) {
        return "未读"
      }
    },
    // 滚动聊天记监听事件
    onScroll({target: {scrollTop}}) {
      console.log("开始滚动");
      const messageListNode = this.$refs['message-list']
      if (!messageListNode) {
        return;
      }
      if (this.preScrollHeight - messageListNode.clientHeight - scrollTop < 20) {
        this.isShowScrollButtomTips = false
      }
    },
    //获取更多的数据 , 获取下一页的数据
    getMoreMessageList() {
      console.log("点击查看更多的聊天消息");
      this.$store.dispatch('timMessage/getMessageList', this.currentConversation.conversationID)
    },
    //指定直接滚动到底部
    scrollMessageListToButtom() {
      console.log("滚动到底部");
      this.$nextTick(() => {
        const messageListNode = this.$refs['message-list']
        if (!messageListNode) {
          return
        }
        messageListNode.scrollTop = messageListNode.scrollHeight
        this.preScrollHeight = messageListNode.scrollHeight
        this.isShowScrollButtomTips = false
        // 消息滚动到底部后，设置消息已读
        this.$store.dispatch('timMessage/setCurrentConversationMessageRead')
      })
    },
    // 格式化时间 , 日期
    formatTime(time) {
      const d = time * 1000;
      var date = new Date(parseInt(d));
      var seperator1 = "-";
      var seperator2 = ":";
      var month = date.getMonth() + 1;
      var strDate = date.getDate();
      var hours = date.getHours();
      var minutes = date.getMinutes();
      var seconds = date.getSeconds();
      //月
      if (month >= 1 && month <= 9) {
        month = "0" + month;
      }
      //日
      if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
      }
      //时
      if (hours >= 0 && hours <= 9) {
        hours = "0" + hours;
      }
      //分
      if (minutes >= 0 && minutes <= 9) {
        minutes = "0" + minutes;
      }
      //秒
      if (seconds >= 0 && seconds <= 9) {
        seconds = "0" + seconds;
      }
      //格式化后日期为：yyyy-MM-dd HH:mm:ss
      var currentdate =
        date.getFullYear() +
        seperator1 +
        month +
        seperator1 +
        strDate +
        " " +
        hours +
        seperator2 +
        minutes +
        seperator2 +
        seconds;
      return currentdate;
    },
    //计算文本消息里面的表情消息 ,
    contentList(message) {
      return decodeText(message.payload)
    },
    //  计算会话的名字 : 就是会话的id
    conversationId() {
      if (this.currentConversation.type === this.TIM.TYPES.CONV_C2C) {
        return (this.currentConversation.userProfile.nick ||
          this.currentConversation.userProfile.userID)
      }
      return "";
    },
    //  判断消息 , 是否是我发的
    isMine(message) {
      return message.flow === 'out'
    },
    //  计算滚动条的进度
    percentage(message) {
      return Math.floor((message.progress || 0) * 100)
    }
  },
}
</script>
<style lang="scss" scoped>

.more {
  display: flex;
  justify-content: center;
  font-size: 12px;
}

.no-more {
  display: flex;
  justify-content: center;
  color: #a5b5c1;
  font-size: 12px;
  padding: 10px 10px;
}

#app1 {
  font-size: 14px;
  font-weight: 400;
  height: 10px;
  text-align: left;
  padding-left: 10px;
}

#app2 {
  border-top: 1px solid #b0b0b0;
  width: 100%;
}


//指定聊天人的名字
#app1 {
  font-size: 14px;
  font-weight: 400;
  height: 10px;
  text-align: left;
  padding-left: 10px;
}

// 聊天的边框样式
.chat {
  background-color: white;
  border-top: 1px solid #b0b0b0;
  border-bottom: 1px solid #b0b0b0;
  width: 100%;
  height: 500px;
  min-height: calc(100vh - 260px);
  max-height: 800px;
  flex-direction: column;
  overflow-y: scroll;

  //指定聊天的消息
  .chat-message {
    margin: 20px 10px;

    //消息的时间
    .message-date {
      color: #999;
      font-size: 12px;
      font-style: normal;
      line-height: 24px;
      text-align: left;
    }

    //用户的消息 , 包含,  头像 , 聊天消息(默认的是 左边的消息样式)
    .message-info {
      //  指定布局
      display: flex;
      //头像
      .message-avatar {
        .avatar {
          box-shadow: 0 2px 7px rgba(100, 100, 100, .6);
        }

      }

      //内容
      .chat-text {
        position: relative;
        //指定最大的宽度
        max-width: 70%;
        height: 100%;
        min-width: 20px;
        min-height: 10px;
        margin-left: 10px;
        //指定边框的圆角
        border-radius: 7px;
        //指定内容边距
        padding: 10px;
        //指定字体的大小
        font-size: 15px;
        //指定颜色
        color: #2b2d33;
        font-family: 微软雅黑;
        letter-spacing: 1px;
        /*  设置气泡的阴影*/
        box-shadow: 0 5px 10px rgba(120, 120, 120, 1);
        background-color: #eaedf3;
      }

      //是否已读
      .isRead {
        margin-top: 10px;
        margin-left: 5px;
        font-size: 12px;
        color: #6e7981;
      }
    }

    //右边消息的样式
    .message-info-right {
      flex-direction: row-reverse;

      .chat-text-right {
        background-color: #cce4fc;
        margin-right: 10px;

      }
    }
  }
}

//左边的消息时间
.message-date-left {
  //  指定消息 , 在左边 , 不用指定
  display: flex;
  //指定消息的展示 在右边
  flex-direction: row;
  margin-left: 60px;
}

//右边的消息时间
.message-date-right {
  display: flex;
  //指定消息的展示 在右边
  flex-direction: row-reverse;
  padding-right: 60px;
}

// 展示文件消息的父容器
.file-element-wrapper {
  width: 150px;
  height: 100px;
  cursor: pointer;
  //  设置一个背景图片
  /*设置背景图片*/
  background-image: url("file.png");
  /*图片只显示一张*/
  background-repeat: no-repeat;
  /*使图片居中显示*/
  background-position: center;
  //  设置图片大小
  background-size: 150px 120px;
}

.file-element {
  //设置字体
  font-family: 微软雅黑;

  display: flex;
  font-size: 15px;
  flex-direction: column;
  padding-top: 28%;
  margin-left: 25%;
}

.file-size {
  font-size: 10px;
  padding-top: 5px;
}

.newMessageTips {
  padding: 5px;
  width: 120px;
  margin: auto;
  bottom: 5px;
  font-size: 12px;
  text-align: center;
  border-radius: 10px;
  border: #e9eaec 1px solid;
  background-color: #ffffff;
  color: #2d8cf0;
  z-index: 1;
}


</style>
